/**
 * 量能活跃度 LNHY 众赢投顾 副图指标
 */

import { movingAverage } from './MA'
import * as zytgTools from './ZYTG_UTIL'

const LNHY_HSL_INDEX = 4 //换手率计算倍数
const LNHY_ZOOM_INDEX = 100 //动能放大倍数，用于显示
const LNHY_LEFT_PADDING_FOR_MA = 60 //左侧多算数据，为ma ms准备

let initParam = {
  name: 'LNHY',
  type: 'polyline',
  caculateParam: [200], // 默认用
}

/**
 * Caculator 数据处理
 *
 * @param  {array} rawData
 * @param  {array} caculateParam
 * @param  {int} dataSliceCount //额外前置增补数据数量 
 * @return {}
 *
 * 使用说明（render.k.chart.js CaclLNHY）：
 *
 * 数据结构说明（从PA开始统一所有指标的结构体）
  {
    "info": {id: "LNHY", title: "量能活跃度"},
    "curves": [
        {title: '活跃度', curve: [1.86, 1.705, 1.7867], color: ['red','green'], fill: true},
    ],
    "icons": [
      {icon: "up_arrow", time: "2017-02-13", color: "red", x: 82, y: 0.656}
    ],
    "rects": [],
    "lines": []
  }
 */
function caculate(rawData, caculateParam, dataSliceCount, summary) {
  // console.log("LNHY raw data count", rawData.length)
  if (!(rawData instanceof Array)) throw new Error('Data or caculateParam is not Array')
  let period = (caculateParam instanceof Array) ? caculateParam[0] : PA_COMPARE_DAYS
  let mathData = _caculator(rawData, period, dataSliceCount, summary)
  return mathData
}

function _caculator(rawData, period, dataSliceCount, summary) {
  //预先计算各个K点的多个指标值
  //定义A（收盘价*3+最低价+开盘价+最高价）/6
  let A_values = zytgTools.calcDays(rawData, [function (raw, index) {
    let day = raw[index]
    return (3 * day.close + day.low + day.open + day.high) / 6
  }
  ])
  //定义B，（A*20+一日前的A值*19+两日前的A值*18+......+18日前的A值*2+20日前的A值）/210
  let B_values = zytgTools.calcDays(rawData, [function (raw, index, extra) {
    const Calc_Period_Of_VarB = 20;
    const Calc_Divider_Of_VarB = 210;
    let day = raw[index]
    let varB = 0;
    for (let j = Calc_Period_Of_VarB; j > 0; j--) {
      let indexA = Math.max(index + j - Calc_Period_Of_VarB, 0);
      varB += j * extra[indexA]
    }
    return (varB / Calc_Divider_Of_VarB)
  }
  ], A_values)
  let MA_B = movingAverage(B_values, 10)

  let maArray = zytgTools.calcMAByFields(rawData, [
    { field: "close", period: "60" },
    { field: "high", period: "60" }
  ])
  //60天最高成交量
  let maxVol60Days = zytgTools.calcMaxMinOfDays(rawData, 'volume', 60, zytgTools.MMD_GET_MAX)
  //120天的最低成交量
  let minVol120Days = zytgTools.calcMaxMinOfDays(rawData, 'volume', 120, zytgTools.MMD_GET_MIN)
  //120日的高点
  let high120Days = zytgTools.calcMaxMinOfDays(rawData, 'high', 120, zytgTools.MMD_GET_MAX)
  let HSLDays = [];   //HSL 换手率数组（短线量能的基础指标）
  let QSLNDays = [];  //趋势量能数组
  let times = [];     //时间数组
  let icons = [];     //图标数组

  let leftPadding = (dataSliceCount > LNHY_LEFT_PADDING_FOR_MA) ? LNHY_LEFT_PADDING_FOR_MA : dataSliceCount
  for (let i = dataSliceCount - leftPadding; i < rawData.length; i++) {
    let day = rawData[i];
    let preDayIndex = i ? i - 1 : 0;

    //定义D，B的10天算术平均值
    let varD = MA_B[i]
    //FF,收盘价>1日前的120日内最高价的最高值
    let readyFF = day.close >= high120Days[preDayIndex]
    //{hsl，即换手率，如果是上交所、深交所的股票，就取值100*vol/流通股本，如果不是，取值vol}
    let varHSL;
    if (summary.market == 'XSHE.MRI' || summary.market == 'XSHG.MRI') {
      varHSL = 1000 * day.volume / (summary.circulation_amount ? summary.circulation_amount : 10000000)
    } else {
      if ((summary.symbol.substring(7) == 'SZ' || summary.symbol.substring(7) == 'SS')) {
      varHSL = 100 * day.volume / (summary.circulation_amount ? summary.circulation_amount : 100)
      } else {
        varHSL = day.volume
      }
    }
    HSLDays.push(varHSL * LNHY_HSL_INDEX * LNHY_ZOOM_INDEX)

    //开始计算图标
    //定义TL60，成交量是60天的最高量，并且 收盘大于60日均线
    let isTop60 = (day.volume >= maxVol60Days[i]) && (day.close > maArray.close60[i])

    //定义TP120，同时满足满足FF条件、收涨超过5%、收阳、收盘大于最高价的60日均线、B值大于D值、最低价大于B和D值
    let isTop120 = readyFF
    isTop120 = isTop120 && (day.close > rawData[preDayIndex].close * 1.05) && (day.close > day.open)
    isTop120 = isTop120 && (day.close > maArray.high60[i])
    isTop120 = isTop120 && (B_values[i] > varD) && (day.low > B_values[i]) && (day.low > varD)

    let need2Show = i >= dataSliceCount
    let volTop60 = need2Show && (isTop60 ? day.volume : 0);
    let volTop120 = need2Show && (isTop120 ? day.volume : 0);
    let issuePastDays = zytgTools.calcPastDays(summary.issue_date, rawData[i].time)
    //在上市后前60日不标注太阳和闪电
    volTop60 = volTop60 && (issuePastDays > 60)
    volTop120 = volTop120 && (issuePastDays > 60)
    //{当TL60V的值不等于TP120V时，满足TL60时，标绿色闪电图标}
    if (isTop60 && (volTop60 != volTop120)) {
      icons.push({
        icon: "light", time: day.time, color: "green", x: i - dataSliceCount, y: 0
      })
    }
    //{当满足TP120条件时，标红色向太阳图标}
    if (isTop120) {
      icons.push({
        icon: "sun", time: day.time, color: "red", x: i - dataSliceCount, y: 0
      })
    }
    //{当满足成交量为120天的最低量，并且并非一字涨停时，标蓝色小圆圈}
    let isCircle = need2Show && (day.volume <= minVol120Days[i])
    isCircle = isCircle && !(day.high == day.low && day.close == day.open && day.high == day.close)
    //在上市后前120日不标注月亮
    isCircle = isCircle && (issuePastDays > 120)
    if (isCircle) {
      icons.push({
        icon: "circle", time: day.time, color: "blue", x: i - dataSliceCount, y: 0
      })
    }

    //{定义VA，如果收涨，取值HSL，如果没收红，取值-HSL}
    let varVA = (day.close > rawData[preDayIndex].close) ? varHSL : (0 - varHSL)
    //{定义趋势量能OBV，如果收盘价=1日前的收盘价,取0,否则取值VA}
    let varQSLN = (day.close == rawData[preDayIndex].close) ? 0 : varVA
    QSLNDays.push({
      "time": rawData[i].time,
      "value": varQSLN * LNHY_ZOOM_INDEX,
    })
    times.push(rawData[i].time);    
  }

  let QSLNDaysValue = []
  QSLNDays.forEach(d => {
    QSLNDaysValue.push(d.value)
  })
  //求30天内的VA累和
  let curveQSLN = zytgTools.movingSum(QSLNDaysValue, 30)
  curveQSLN = movingAverage(curveQSLN, 10)
  curveQSLN.forEach((d, i) => {
    QSLNDays[i].value = +d.toFixed(2)
  })

  //短线量能：5天的HSL*4平均值减60天的hsl*4平均值，然后乘2
  let hslMA5 = movingAverage(HSLDays, 5);
  let hslShort = zytgTools.calcArrays(hslMA5, movingAverage(HSLDays, 60), function (a, b) {
    return (a - b) * 2
  })

  //定义HSL，当上市后前60个交易日，取值5天的HSL*4平均值减60天的hsl*4平均值，在60 个交易日（包含60）后，取值短线量能
  let hslMA10 = movingAverage(HSLDays, 10);
  //短线量能曲线
  let curveDXLN = hslShort.slice(0);
  for (let i = 0; i < curveDXLN.length; i++) {
    if (zytgTools.calcPastDays(summary.issue_date, rawData[i - leftPadding + dataSliceCount].time) >= 60) {
      break
    }
    curveDXLN[i] = hslMA5[i] - hslMA10[i]
  }

  let _curveDXLN = []
  for (let i = leftPadding; i < curveDXLN.length; i++) {
    let day = {
      "time": times[i],
      "value": +curveDXLN[i].toFixed(2)
    } 
    _curveDXLN.push(day)
  }
  
  // 赋予icon和短线量能对应的高度
  icons.forEach(d => {
    _curveDXLN.forEach(curve => {
      if (d.time === curve.time) {
        d.y = curve.value
      }
    })
  })

  let result = {
    info: { id: "LNHY", title: "量能活跃度" },
    curves: [
      { title: '短线量能', curve: _curveDXLN, color: ['red', 'green'], fill: true },
      { title: '趋势量能', curve: QSLNDays.slice(leftPadding), color: ['blue'] }
    ],
    icons: icons
  }
  return result
}


export default {
  initParam: initParam,
  caculate: caculate
}